package org.pjx.spm.util.kaptcha;

import org.pjx.spm.pojo.VerifyCode;
import org.pjx.spm.util.config.VerifyCodeGeneral;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Random;
import org.pjx.spm.util.kaptcha.RandomUtils;
/**
 * @Author Glow
 * @Date 2022-01-28 23:26:07
 * @Description 验证码实现类
 * @Version 1.0
 */
public class VerifyCodeKaptchaConfig implements VerifyCodeGeneral {
    //logger 记录报错
    private static final Logger logger = LoggerFactory.getLogger(VerifyCodeKaptchaConfig.class);
    //字体类型
    private static final String[] FONT_TYPES = { "\u5b8b\u4f53", "\u65b0\u5b8b\u4f53", "\u9ed1\u4f53", "\u6977\u4f53", "\u96b6\u4e66" };
    //验证码长度
    private static final int VALICATE_CODE_LENGTH = 4;
    /**
     * 设置图片背景颜色及大小
     * @param graphics
     * @param width
     * @param height
     */
    private static void fillBackground(Graphics graphics,int width,int height)
    {
        //设置图片背景颜色
        graphics.setColor(Color.WHITE);
//        设置图片长宽
        graphics.setClip(0,0,width,height);
//        加入图片线条，尽可能避免AI识别
        for(int i = 0 ; i < 8 ; i++)
        {
//        随机线条颜色以及线条摆放位置
            graphics.setColor(RandomUtils.randomColor(30,200));
            Random ram = new Random();
            int sx = ram.nextInt(width);
            int sy = ram.nextInt(height);
            int wid = ram.nextInt(width);
            int hei = ram.nextInt(height);
            graphics.drawLine(sx,sy,wid,hei);
        }
    }

    /**
     * 设置字符颜色和大小
     * @param graphics
     * @param randomStr
     */
        private  void createCharacter(Graphics graphics,String randomStr)
        {
                    char[] randomStrChar = randomStr.toCharArray();
                    for (int i = 0 ; i<randomStrChar.length; i++)
                    {
                        //设置字符颜色
                        graphics.setColor(new Color(50+RandomUtils.nextInt(100),50+RandomUtils.nextInt(100),50+RandomUtils.nextInt(100)));
                        //设置字体大小
                        graphics.setFont(new Font(FONT_TYPES[RandomUtils.nextInt(FONT_TYPES.length)],Font.BOLD,24));
                        //设置x，y中心放置坐标
                        graphics.drawString(String.valueOf(randomStrChar[i]),15 * i + 5,19 + RandomUtils.nextInt(8));
                    }
        }
    /**
     * 生成随机字符构成验证码
     * @param width
     * @param height
     * @param outputStream
     * @return
     * @throws IOException
     */
    @Override
    public String generate(int width, int height, OutputStream outputStream) throws IOException {
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);
        Graphics graphics = image.getGraphics();
        fillBackground(graphics,width,height);
        String randomStr = RandomUtils.randomString(VALICATE_CODE_LENGTH);
        //设置验证码颜色及其大小样式
        createCharacter(graphics,randomStr);
        graphics.dispose();
        //设置jpeg图片格式
        ImageIO.write(image,"JPEG",outputStream);
        return randomStr;
    }
    //生成验证码
    @Override
    public VerifyCode generate(int width, int height) throws IOException {
        VerifyCode verifyCode = null;
        try(ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream()){
            String code = generate(width,height,byteArrayOutputStream);
            verifyCode = new VerifyCode();
            verifyCode.setCode(code);
            verifyCode.setImgBytes(byteArrayOutputStream.toByteArray());


        }
        catch (IOException e )
        {
            logger.error(e.getMessage(),e);
            verifyCode = null ;
        }
        return verifyCode;
    }
}
